package com.softer.wxzj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.softer.wxzj.common.entity.CommonResult;
import com.softer.wxzj.common.entity.Page;
import com.softer.wxzj.common.enums.NumStrEnum;
import com.softer.wxzj.common.enums.NumberEnum;
import com.softer.wxzj.common.enums.ShiroResultEnum;
import com.softer.wxzj.common.error.CourseException;
import com.softer.wxzj.common.logic.CalculateAmount;
import com.softer.wxzj.common.util.DateUtils;
import com.softer.wxzj.common.util.ShiroUserUtil;
import com.softer.wxzj.common.util.StringUtils;
import com.softer.wxzj.common.util.UUIDUtil;
import com.softer.wxzj.entity.*;
import com.softer.wxzj.mapper.*;
import com.softer.wxzj.service.BaseBuildInfoService;
import com.softer.wxzj.service.BaseCellInfoService;
import com.softer.wxzj.service.DepModeInfoService;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author ludexing
 * @Date 2019-6-25 20:28
 */
@Service
public class DepModeInfoServiceImpl implements DepModeInfoService {
    @Autowired
    private DepModeInfoMapper depModeInfoMapper;
    @Autowired
    private BaseHouseInfoMapper baseHouseInfoMapper;
    @Autowired
    private BaseBuildInfoService baseBuildInfoService;
    @Autowired
    private BaseCellInfoService baseCellInfoService;
    @Autowired
    private CalculateAmount calculateAmount;
    @Autowired
    private AccTransactionLogMapper accTransactionLogMapper;
    @Autowired
    private BaseOwnerInfoMapper baseOwnerInfoMapper;
    @Autowired
    private BaseBuildInfoMapper baseBuildInfoMapper;
    @Autowired
    private BaseCellInfoMapper baseCellInfoMapper;
    @Autowired
    private BaseModifyDetailMapper baseModifyDetailMapper;

    @Override
    public CommonResult insert(DepModeInfo depModeInfo) {
        CommonResult commonResult = checkDepModeInfo(depModeInfo);
        if (commonResult == null) {
            String idByName = depModeInfoMapper.getIdByName(depModeInfo.getName());
            if (StringUtils.isNotEmpty(idByName)){
                return CommonResult.ResponseResult(0,"交存模式名称相同，请重新填写");
            }
            depModeInfo.setId(UUIDUtil.getUUID());
            String userName = ShiroUserUtil.getUserName();
            depModeInfo.setCreater(userName);
            depModeInfo.setModifier(userName);
            String state = checkTime(depModeInfo);
            depModeInfo.setState(state);
            if (StringUtils.isBlank(depModeInfo.getEndTime())) {
                depModeInfo.setEndTime(null);
            }
            int ret = depModeInfoMapper.insert(depModeInfo);
            return CommonResult.ResponseResult(ret);
        }
        return commonResult;
    }

    /**
     * 判断该交存模式是否启用
     *
     * @param depModeInfo 交存模式
     */
    public String checkTime(DepModeInfo depModeInfo) {
        if (DateUtils.checkTime(depModeInfo.getStartTime())) {
            String endTime = depModeInfo.getEndTime();
            if (StringUtils.isNotEmpty(endTime)) {
                if (DateUtils.checkTime(endTime)) {
                    return String.valueOf(NumberEnum.ZERO.getNum());
                } else {
                    return String.valueOf(NumberEnum.ONE.getNum());
                }
            } else {
                return String.valueOf(NumberEnum.ONE.getNum());
            }
        } else {
            return String.valueOf(NumberEnum.ZERO.getNum());
        }
    }

    @Override
    public CommonResult update(DepModeInfo depModeInfo) {
        CommonResult commonResult = checkDepModeInfo(depModeInfo);
        if (null == depModeInfo.getConstructionCost()) {
            depModeInfo.setConstructionCost(BigDecimal.ZERO);
        }
        int ret = 0;
        if (commonResult == null) {
            String state = checkTime(depModeInfo);
            depModeInfo.setState(state);
            depModeInfo.setModifier(ShiroUserUtil.getUserName());
            DepModeInfo oldDepModeInfo = depModeInfoMapper.getInfo(depModeInfo.getId());
            if (!oldDepModeInfo.getDepType().equals(depModeInfo.getDepType()) && depModeInfo.getDepType().equals(NumStrEnum.ONE.getNum())) {
                ret = depModeInfoMapper.update(depModeInfo);
                List<String> houseId = baseHouseInfoMapper.selectByDep(depModeInfo.getId());
                for (String house : houseId) {
                    BaseOwnerInfo baseOwner = baseOwnerInfoMapper.getInfoByAccNo(house);
                    if (null != baseOwner) {
                        if (null == baseOwner.getPrice() || baseOwner.getPrice().compareTo(BigDecimal.ZERO) == 0) {
                            throw new CourseException(ShiroResultEnum.FAIL.getCode(), "请先维护业主的售价再更改缴存标准");
                        }
                    }
                    updateHouse(house, depModeInfo);
                }
            } else {
                ret = depModeInfoMapper.update(depModeInfo);
                List<String> houseId = baseHouseInfoMapper.selectByDep(depModeInfo.getId());
                for (String house : houseId) {
                    updateHouse(house, depModeInfo);
                }
            }
            return CommonResult.ResponseResult(ret);
        }
        return commonResult;
    }

    public void updateHouse(String house, DepModeInfo depModeInfo) {
        BaseHouseInfo b = baseHouseInfoMapper.getInfo(house);
        BaseHouseInfo base = new BaseHouseInfo();
        base.setId(b.getId());
        BigDecimal bigDecimal = calculateAmount.calculateDueAmountDep(b, depModeInfo);
        base.setFirstDue(bigDecimal);
        BigDecimal outMoney = accTransactionLogMapper.selectMoneyReqAll(b.getId());
        BigDecimal inMoney = accTransactionLogMapper.selectMoneyDepAll(b.getId());
        BigDecimal money = inMoney.subtract(outMoney);
        if (money.compareTo(BigDecimal.ZERO) == 0) {
            base.setDueState(NumStrEnum.FOUR.getNum());
        } else if (bigDecimal.compareTo(money) > 0) {
            base.setDueState(NumStrEnum.THREE.getNum());
        } else if (bigDecimal.compareTo(money) == 0) {
            base.setDueState(NumStrEnum.ONE.getNum());
        } else {
            base.setDueState(NumStrEnum.TWO.getNum());
        }
        baseHouseInfoMapper.update(base);
    }

    /**
     * house表中   有 缴存 id的  就不能删
     *
     * @param id
     * @return
     */
    @Override
    public CommonResult delete(String id) {
        var info = new BaseHouseInfo();
        info.setFirstMode(id);
        var list = baseHouseInfoMapper.getList(info);
        if (list.isEmpty()) {
            return depModeInfoMapper.delete(id) > 0 ? CommonResult.ResponseResult(1) : CommonResult.ResponseResult(0, "删除失败");
        } else {
            return CommonResult.ResponseResult(0, "存在业务");
        }

    }

    @Override
    public PageInfo<DepModeInfo> getList(Page page, DepModeInfo depModeInfo) {
        List<DepModeInfo> list;
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        if (StringUtils.isNotEmpty(depModeInfo.getFuzzy())) {
            //模糊查询
            list = depModeInfoMapper.getFuzzyList(depModeInfo.getFuzzy());
        } else {
            //精确查询
            list = depModeInfoMapper.getList(depModeInfo);
        }
        var pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    @Override
    public DepModeInfo getInfo(String id) {
        int count = baseHouseInfoMapper.selectDepCount(id);
        DepModeInfo d = depModeInfoMapper.getInfo(id);
        if (count > 0) {
            d.setState(NumStrEnum.ZERO.getNum());
        }
        return d;
    }

    /**
     * 公共 save 方法
     *
     * @param depModeInfo
     * @return
     */
    @Override
    public CommonResult save(DepModeInfo depModeInfo) {
        CommonResult commonResult = checkDepModeInfo(depModeInfo);
        if (commonResult == null) {
            String id = depModeInfo.getId();
            var info = new DepModeInfo();
            info.setName(depModeInfo.getName());
            //修改逻辑
            var list = depModeInfoMapper.getList(info);
            if (StringUtils.isEmpty(id)) {
                //新增 逻辑
                if (!list.isEmpty()) {
                    return CommonResult.strResult(0, "缴存模式名称重复");
                } else {
                    var ret = depModeInfoMapper.insert(depModeInfo);
                    return CommonResult.ResponseResult(ret);
                }
            } else {
                if (list.size() == 1 && list.get(0).getId().equals(id)) {
                    var ret = depModeInfoMapper.update(depModeInfo);
                    return CommonResult.ResponseResult(ret);
                } else {
                    return CommonResult.strResult(0, "缴存模式名称重复");
                }
            }
        }

        return commonResult;
    }

    /**
     * 启用
     *
     * @param depModeInfo
     * @return
     */
    @Override
    public CommonResult enable(DepModeInfo depModeInfo) {
        DepModeInfo info = depModeInfoMapper.getInfo(depModeInfo.getId());
        String num = checkTime(info);

        if (String.valueOf(NumberEnum.ZERO.getNum()).equals(num)) {
            return CommonResult.ResponseResult(NumberEnum.ZERO.getNum(), "不在时间范围内，请确认启用时间和停用时间");
        }
        return depModeInfoMapper.update(depModeInfo) > 0 ? CommonResult.ResponseResult(1) : CommonResult.ResponseResult(0, "操作失败");
    }

    @Override
    public List<DepModeInfo> selectByAllChange(DepModeInfo depModeInfo) {
        List<DepModeInfo> d = new ArrayList<>();
        BaseBuildInfo baseBuild = new BaseBuildInfo();
        BaseCellInfo baseCellInfo = new BaseCellInfo();
        BaseHouseInfo base = new BaseHouseInfo();
        //查询房屋
        if (StringUtils.isBlank(depModeInfo.getCellId())) {
            base = baseHouseInfoMapper.getInfo(depModeInfo.getHouseId());
            if (null != base) {
                baseCellInfo = baseCellInfoMapper.getInfo(base.getCellNo());
                //若是刚添加的
            } else {
                base = new BaseHouseInfo();
                String buildNo = baseModifyDetailMapper.selectBuidNoByHouseId(depModeInfo.getHouseId(), "buildNo");
                String elevator = baseModifyDetailMapper.selectBuidNoByHouseId(depModeInfo.getHouseId(), "elevator");
                String cellId = baseModifyDetailMapper.selectBuidNoByHouseId(depModeInfo.getHouseId(), "cellNo");
                baseCellInfo.setBuildNo(buildNo);
                baseCellInfo.setElevator(elevator);
                baseCellInfo.setId(cellId);
            }
        } else {
            baseCellInfo = baseCellInfoMapper.getInfo(depModeInfo.getCellId());
            if (null == baseCellInfo) {
                baseCellInfo = new BaseCellInfo();
                String ele = baseModifyDetailMapper.selectEle(depModeInfo.getCellId());
                String buildNo = baseModifyDetailMapper.selectBuidNo(depModeInfo.getCellId());
                baseCellInfo.setBuildNo(buildNo);
                baseCellInfo.setElevator(ele);
            }
        }
        depModeInfo.setElevator(baseCellInfo.getElevator());
        baseBuild = baseBuildInfoMapper.getInfo(baseCellInfo.getBuildNo());
        depModeInfo.setBiuldStructure(baseBuild.getBuildAttr());
        depModeInfo.setBuildType(baseBuild.getBuildType());
        d = depModeInfoMapper.selectByAllChange(depModeInfo);
        for (DepModeInfo dep : d) {
            if (NumStrEnum.ONE.getNum().equals(dep.getState())){
                dep.setState("true");
            }else {
                dep.setState("false");
            }
        }
        String s = JSON.toJSONString(d, SerializerFeature.DisableCircularReferenceDetect);
        List<DepModeInfo> list = JSON.parseObject(s, List.class);
        return list;
    }

    @Override
    public List<DepModeInfo> getListByHouseId(String houseId) {
        var houseInfo = baseHouseInfoMapper.getInfo(houseId);
        DepModeInfo depModeInfo = new DepModeInfo();
        depModeInfo.setBuildType(baseBuildInfoService.getInfo(houseInfo.getBuildNo()).getBuildType());
        depModeInfo.setElevator(baseCellInfoService.getInfo(houseInfo.getCellNo()).getElevator());
        depModeInfo.setHouseType(houseInfo.getHouseAttr());
        depModeInfo.setHouseNature(houseInfo.getHouseUse());
        depModeInfo.setBiuldStructure(baseBuildInfoService.getInfo(houseInfo.getBuildNo()).getBuildType());
        depModeInfo.setDepType("");
        return depModeInfoMapper.getList(depModeInfo);
    }

    @Override
    public List<DepModeInfo> getListNoPage(String modeType) {
        return depModeInfoMapper.getListNoPage(modeType);
    }
}
